(* This is a definition of a structure named "Interp" *) 
structure Interp = 
struct

(* The following statement defines a short name for structure 
 * SLP, so you can use S.CompoundStm, S.Plus, S.IdExp, etc. 
 * to refer to items defined in structure SLP (see slp.sml) 
 *)
structure S = SLP
	      
(* This statement renames type of "(S.id * int) list" as 
 * table. We need a symbol table of this
 * type to maintain a list of (variable, integer)pairs.
 *)
type table = (S.id * int) list
	     
(* This function adds ('ident', 'newval') to the symbol 
 * table(or symbol list) 'tbl'. We assume 
 * the first occurrence of any id takes precedence over 
 * any later occurrences in the table.
 *)
fun update(tbl, ident, newval) = (ident, newval)::tbl

exception UndefinedVariable of string
			       
(* This function lookups the 'tbl' using 'ident' as the 
 * key, it returns the value of 'ident'
 * in the 'tbl'.
 *)
fun lookup (tbl:table, ident) = 
    case tbl 
     of nil => raise UndefinedVariable(ident)
      | (x, xval)::xs => 
        if ident=x 
        then xval
	else lookup(xs, ident)
			      
exception Unimplemented
 
(* This function interprets the binary operators *)
val interpOp =
 fn S.Plus => Int.+
  | S.Minus => Int.-
  | S.Times => Int.*
  | S.Div => Int.div
		       
(* These are definitions of two mutually recursive 
 * functions, they interpert statements 's' 
 * by referring symbol table 'tbl'.
 *)
fun interpStm (s: S.stm, tbl: table) = 
    case s 
     of S.CompoundStm slist => raise Unimplemented
      | _ => raise Unimplemented
		
and interpExp (e: S.exp, tbl: table) = 
    case e 
     of S.IdExp(i) =>(lookup(tbl, i), tbl) 
      (*you can also change the handler method of this case*)
      | _ => raise Unimplemented (* add your code here and extend case *)

(* This function is the entry of this file, it packages interpStm(). *)
fun interp s = 
    (interpStm(s, nil); ())


end
